/**
 *  EKology - An Ecosystem Simulation Framework
 *  Copyright (C) 2008  Aarón Tavío - aaron.tavio at gmail.com - ULPGC
 *
 *  This program is free software: you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation, either version 3 of the License, or
 *  (at your option) any later version.
 *
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with this program.  If not, see <http://www.gnu.org/licenses/>.
 * 
 */

package net.ekology.core.gui.datatypes;

import net.ekology.ekosystem.datatypes.Genome;
import net.ekology.ekosystem.Biotope;

import java.util.Vector;
import java.util.Arrays;
import java.io.File;
import java.io.FileInputStream;
import java.io.Serializable;


/**
 * @author Aarón Tavío - aaron.tavio at gmail.com
 * @version 1.0.0 - 20081019-1700
 */
public class EKosystemModel implements Serializable {
    private Vector<Object> vModel;

    
    public EKosystemModel(Vector vModel) {
        this.vModel = vModel;
    }
    
    
    public Vector<Class> getModelAgentClasses() {
        Vector<Class> vResult = new Vector<Class>();
        
        for(Object oObj: vModel) if (oObj instanceof Class) vResult.add((Class) oObj);
        
        return vResult;
    }
    
    
    public Vector<Genome> getModelGenomes() {
        Vector<Genome> vResult = new Vector<Genome>();
        
        for(Object oObj: vModel) if (oObj instanceof Genome) vResult.add((Genome) oObj);
        
        return vResult;
    }
    
    
    public Genome getModelGenome(String sSpeciesName) {
        Genome oResult = null;
        
        for(Object oObj: vModel) if (oObj instanceof Genome && Genome.class.cast(oObj).getSpeciesID().equals(sSpeciesName)) oResult = (Genome) oObj;
        
        return oResult;
    }
    
    
    public Biotope getModelBiotope() {
        return (vModel != null)? (Biotope) vModel.firstElement() : null;
    }
    
    
    public static Vector<Class> getModelClasses(File oModelDirectory) {
        File oSourcesDirectory = new File(oModelDirectory.getPath()+"/ekosystem");
        Vector<Class> vClasses = new Vector<Class>();
        String sClassPrefix = oModelDirectory.getName() + ".ekosystem.";
        
        if (oSourcesDirectory.isDirectory()) {
            for(File oFile: oSourcesDirectory.listFiles()) {
                if (oFile.getName().toLowerCase().endsWith(".class") && oFile.isFile()) {
                    try {
                        vClasses.add(Class.forName(sClassPrefix + oFile.getName().substring(0, oFile.getName().lastIndexOf(".class"))));
                    } catch(Exception e) {
                        e.printStackTrace();
                    }
                }
            }
        }
        
        return vClasses;       
    }
    
    
    public static Vector<Genome> getModelGenomes(File oModelDirectory) {
        File oGenomesDirectory = new File(oModelDirectory.getPath()+"/genomes");
        Vector<Genome> vGenome = new Vector<Genome>();
        Genome oGenome;
        
        
        if (oGenomesDirectory.isDirectory()) {
            for(File oFile: oGenomesDirectory.listFiles()) {
                if (oFile.getName().toLowerCase().endsWith(".genome") && oFile.isFile()) {
                    oGenome = new Genome();
                    try {
                        oGenome.buildFromFile(new FileInputStream(oFile));
                        if (oGenome.getGeneCount() > 0) vGenome.add(oGenome);
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                }
            }
        }
        
        return vGenome;       
    }
       
    
    public static boolean checkValidModel(File oModelDirectory) {
        boolean hasBiotope = false;
        Vector<String> vBioticAgentName = new Vector<String>();
        String sSuperclass;
        String[] aValidSuperclasses = {
                                        "Biotope",
                                        "BioticAgent",
                                        "AbioticAgent"
                                        };
        Vector<String> vValidSuperclasses = new Vector<String>(Arrays.asList(aValidSuperclasses));
        
        for(Class oClass: getModelClasses(oModelDirectory)) {
            sSuperclass = oClass.getSuperclass().getSimpleName();
            if (!vValidSuperclasses.contains(sSuperclass)) return false;
            else if (sSuperclass.equals(aValidSuperclasses[1])) vBioticAgentName.add(oClass.getSimpleName());
            else if (sSuperclass.equals(aValidSuperclasses[0])) {
                if (hasBiotope) return false;
                else hasBiotope = true;
            }
        }
        
        return hasBiotope && checkExistingGenomes(vBioticAgentName,oModelDirectory);
    }
    
    
    public static boolean checkExistingGenomes(Vector<String> vBioticAgentName, File oModelDirectory) {
        boolean bResult = true;
        File oGenomesDirectory = new File(oModelDirectory.getPath()+"/genomes");
        Vector<String> vFilenames;
        
        vFilenames = new Vector<String>(Arrays.asList(oGenomesDirectory.list()));
        for(String sBioticAgentName: vBioticAgentName) {
            if (!vFilenames.contains(sBioticAgentName+".genome")) {
                bResult = false;
                break;
            }
        }
        
        return bResult;
    }
}
